home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-05-25 | 13.0 KB | 490 lines | [TEXT/MACA] |
- ;*
- ;*
- ;* Program Name: Math Facts V1.0
- ;* Date Written: May 11, 1987
- ;* Author: Christopher J. Flynn
- ;* 2601 Claxton Drive
- ;* Herndon, VA 22071
- ;* Description:
- ;* Math Facts is a simple drill and practise game. It presents
- ;* the user with randomly generated arithmetic problems. The
- ;* user responds by clicking on appropriate buttons which are
- ;* displayed on the screen. The program does not keep 'score'
- ;* and problems can be skipped entirely without penalty.
- ;*
- ;* To run, load the file into an edit window. Select all with
- ;* Command-A, run with Command-R. Be patient, compilation takes
- ;* a little while!
- ;*
- ;* NOTE: MacInTalk MUST be in your system folder. This program
- ;* uses speech.
- ;*
- ;* NOTE: for best results, install Monaco 24 in your system file.
- ;*
- ;* NOTE: this program is written in an object-oriented style.
- ;* You can establish multiple instances of the game by typing
- ;* the following lines in the Listener window:
- ;*
- ;* make "NewGameWindow oneof :GameWindow
- ;* MakeSomeButtons :NewGameWindow
- ;*
- ;* Use whatever name you want for the new window.
- ;*
- ;*
- ;* NOTE: Version 1.5 or above of Object Logo is required.
- ;* Conact: Coral Software
- ;* P.O. Box 307
- ;* Cambridge, MA 02142
- ;*
- ;* NOTE: This program may be freely distributed.
- ;*
- ;*
-
-
-
-
- ;
- ; W I N D O W O B J E C T D E F I N I T I O N
- ;
-
- make "GameWindow kindof TurtleWindow
-
- ask :GameWindow [to exist]
- Usual.Exist
- HideTurtle
- SetWSize [505 297]
- SetWTitle "|Math Facts|
- SetWFont "Monaco ;Whatever you wish
- SetWFontSize 24 ;Put exact size in system
- SetWFontStyle [Bold]
- SetPenMode "Reverse
- SetTextMode "Reverse
- HaveMake "KeyPadRect [78 170 407 269] ;Keypad for the game
- HaveMake "ProblemRect [30 40 180 80] ;Problems are displayed here
- HaveMake "AnswerRect [300 40 450 80] ;User's answers
- HaveMake "MessageRect [78 100 407 160] ;Messages
- HaveMake "Gray [170 85 170 85 170 85 170 85]
- HaveMake "LtGray [136 34 136 34 136 34 136 34]
- HaveMake "Black [255 255 255 255 255 255 255 255]
- DrawRectangle :KeyPadRect :Gray
- DrawRectangle :ProblemRect :LtGray
- DrawRectangle :AnswerRect :LtGray
- DisplayAt 40 30 "|What Is?|
- DisplayAt 283 30 "|Your Answer|
- HaveMake "ButtonList [] ;List of all button objects
- HaveMake "YourAnswer " ;Answer entered by human
- HaveMake "MyProblem " ;Generated math problem
- HaveMake "MyAnswer " ;Answer to the problem
- HaveMake "WhatKind "Mixed ;Type of problem
- HaveMake "MaxAugend 50
- HaveMake "MaxAddend 50
- HaveMake "MaxMinuend 50
- HaveMake "MaxSubtrahend 50
- HaveMake "MaxMultiplicand 12
- HaveMake "MaxMultiplier 12
- HaveMake "MaxDividend 100
- HaveMake "maxDivisor 12
- DoNext ;Make the first problem
- end
-
-
- ;
- ; Procedure for drawing a bounded round rectangle and optionally
- ; filling it with a pattern
- ;
-
- ask :GameWindow [to DrawRectangle :Rectangle :Pattern]
- LocalMake "HoldState GetPenState
- SetPenSize 2 2
- EraseRoundRect (InsetRect :Rectangle 2 2) 16 16
- SetPenPat :Black
- SetPenMode "Paint
- FrameRoundRect :Rectangle 16 16
- if not EmptyP :Pattern
- _ [SetPenPat :pattern
- _ PaintRoundRect (InsetRect :Rectangle 2 2) 16 16]
- SetPenState :HoldState
- end
-
-
- ;
- ; Display a string at the specified point.
- ;
- ask :GameWindow [to DisplayAt :X :Y :theText]
- MoveTo :X :Y
- type :theText
- end
-
-
- ;
- ; Intercept and process mouse clicks
- ;
-
- ask :GameWindow [to WClick :X :Y :Mods]
- LocalMake "PressedWhat FindTheButton :ButtonList :X :Y
- if not EmptyP :PressedWhat
- _ [DoActionButton :PressedWhat]
- Usual.WClick :X :Y :Mods
- end
-
-
- ;
- ; Determine if the mouse was clicked in a button. If so,
- ; ask the button to process the click. Output the button
- ; object that was clicked. If not, do nothing with the
- ; and output "false.
- ;
- ; Note: mouse button can be released outside of the
- ; button. This is treated as a non-click.
- ;
-
- ask :GameWindow [to FindTheButton :ButtonList :X :Y]
- if Emptyp :ButtonList [output []]
- LocalMake "Me first :ButtonList
- LocalMake "MyRect ask :Me [:ButtonRect]
- if PtInRectP list :X :Y :MyRect
- _ [ask :Me [ClickButton]
- _ ifelse PtInRectp list mousex mousey :MyRect
- _ [output ask :Me [:ButtonLabel]]
- _ [output []]]
- FindTheButton butfirst :ButtonList :X :Y
- end
-
- ;
- ; G A M E - R E L A T E D P R O C E D U R E S
- ;
- ; These procedures are defined in the window object. The procedures
- ; faciltate interaction with the user by obtaining and acting on
- ; "clicks" from the button objects.
- ;
-
-
- ;
- ; Determine what to do when a button is "clicked".
- ;
-
- ask :GameWindow [to DoActionButton :WhichButton]
- ifelse Equalp :WhichButton "|Next|
- _ [DoNext]
- _ [ifelse EqualP :WhichButton "|O.K.!|
- _ [DoOK]
- _ [ifelse EqualP :WhichButton "|Help|
- _ [DoHelp]
- _ [ifelse EqualP :WhichButton "|Oops!|
- _ [DoOops]
- _ [DoDigit :WhichButton]]]]
- end
-
-
- ;
- ; Process Next - Make a new math problem. The type of operation
- ; is specified by :WhatKind. Display the problem and save the answer.
- ;
-
- ask :GameWindow [to DoNext]
- ask oneof speaker [speak "Next]
- DrawRectangle :ProblemRect :LtGray
- DrawRectangle :AnswerRect :LtGray
- EraseRect :MessageRect
- HaveMake "MyProblem MakeProblem :WhatKind
- HaveMake "MyAnswer Run :MyProblem
- DisplayTheProblem :MyProblem
- HaveMake "YourAnswer "
- end
-
- ask :GameWindow [to DisplayTheProblem :Problem]
- LocalMake "X item 1 :ProblemRect
- LocalMake "Y item 2 :ProblemRect
- Local [Operator OpWord]
- EraseRoundRect (InsetRect :ProblemRect 2 2) 16 16
- MoveTo :X :Y
- Move 15 WFontSize + 4
- Type :Problem
- ask oneof speaker [speak "|What is|]
- ask oneof speaker [speak item 1 :Problem]
- make "Operator item 2 :Problem
- if Equalp :Operator "+ [make "OpWord "Plus]
- if Equalp :Operator "- [make "OpWord "Mighnus]
- if Equalp :Operator "* [make "OpWord "Times]
- if Equalp :Operator "/ [make "OpWord "|Divided By|]
- ask oneof speaker [speak :OpWord]
- ask oneof speaker [speak item 3 :Problem]
- end
-
-
- ;
- ; Process OK - Check your answer agaisnt my answer
- ;
-
- ask :GameWindow [to DoOK]
- ask oneof speaker [speak "|O. K.|]
- ifelse EqualP :MyAnswer :YourAnswer
- _ [DisplayCorrect
- _ DoNext]
- _ [DisplayIncorrect
- _ DrawRectangle :AnswerRect :LtGray
- _ HaveMake "YourAnswer " ]
- end
-
- ask :GameWindow [to DisplayCorrect]
- LocalMake "Temp Pick
- _ [|Very Good!| |Excellent!| |That's Right!| |Super!|
- _ |Good Job!| |Correct!| |Excellent!| |You Got It!|]
- ask oneof speaker [speak :Temp]
- DisplayMessage :Temp
- Wait 2
- end
-
- ask :GameWindow [to DisplayIncorrect]
- LocalMake "Temp Pick
- _ [|Sorry!| |Try Again!| |I Don't Think So!|
- _ |No.| |Look At It Again!| |Are You Kidding!|]
- ask oneof speaker [speak :Temp]
- DisplayMessage :Temp
- Wait 2
- EraseRect :MessageRect
- end
-
-
- ;
- ; Process Help - Display the answer, pause, make another problem
- ;
-
- ask :GameWindow [to DoHelp]
- LocalMake "Ans :MyAnswer
- ask oneof speaker [speak "Help]
- DisplayMessage (se "|The answer is| :MyAnswer)
- ask oneof speaker [speak (word "|The answer is| :Ans)]
- wait 5
- HaveMake "YourAnswer "
- DoNext
- end
-
-
- ask :GameWindow [to DisplayMessage :What]
- LocalMake "X item 1 :MessageRect
- LocalMake "Y item 2 :MessageRect
- EraseRect :MessageRect
- MoveTo :X :Y
- Move 1 WFontSize + 4
- Type :What
- end
-
-
- ;
- ; Process Oops! - Erase answer entered so far.
- ;
-
- ask :GameWindow [to DoOops]
- ask oneof speaker [speak "Oops]
- HaveMake "YourAnswer "
- DrawRectangle :AnswerRect :LtGray
- end
-
-
- ;
- ; Collect digit "clicks" into an answer
- ;
-
- ask :GameWindow [to DoDigit :WhichButton]
- ask oneof speaker [speak :WhichButton]
- HaveMake "YourAnswer word :YourAnswer :WhichButton
- if greaterp (count :YourAnswer) 5
- _ [HaveMake "YourAnswer butfirst :YourAnswer]
- DisplayYourAnswer :YourAnswer
- end
-
-
- ;
- ; Display human's answer
- ;
-
- ask :GameWindow [to DisplayYourAnswer :Answer]
- LocalMake "X item 1 :AnswerRect
- LocalMake "Y item 2 :AnswerRect
- EraseRoundRect (InsetRect :AnswerRect 2 2) 16 16
- MoveTo :X :Y
- Move 34 WFontSize + 4
- Type :Answer
- end
-
- ;
- ; P R O B L E M G E N E R A T I O N P R O C E D U R E S
- ;
-
- ask :GameWindow [to Pick :theList]
- op item 1 + random count :theList :theList
- end
-
- ;
- ; Generate a new problem based on the operator
- ;
-
- ask :GameWindow [to MakeProblem :WhatProblem]
- if EqualP :WhatProblem "+ [op MakeAddition]
- if EqualP :WhatProblem "- [op MakeSubtraction]
- if EqualP :WhatProblem "* [op MakeMultiplication]
- if EqualP :WhatProblem "/ [op MakeDivision]
- MakeProblem Pick [+ - * /]
- end
-
-
- ;
- ; Generate problems. Magnitudes of the operands are governed
- ; by global variables. Note that subtraction and division require
- ; special attention.
- ;
-
- ask :GameWindow [to MakeAddition]
- op (se (random :MaxAugend) "+ (random :MaxAddend))
- end
-
- ask :GameWindow [to MakeSubtraction]
- LocalMake "Minuend random :MaxMinuend
- DoUntil [LocalMake "Subtrahend random :MaxSubtrahend]
- _ [or (LessP :Subtrahend :Minuend) (EqualP :Subtrahend :Minuend)]
- op (se :Minuend "- :Subtrahend)
- end
-
- ask :GameWindow [to MakeMultiplication]
- op (se (random :MaxMultiplicand) "* (random :MaxMultiplier))
- end
-
- ask :GameWindow [to MakeDivision]
- LocalMake "Divisor 1 + random :MaxDivisor
- DoUntil [LocalMake "Dividend 1 + random :MaxDividend]
- _ [(and
- _ (or (GreaterP :Dividend :Divisor) (EqualP :Dividend :Divisor))
- _ (EqualP (Remainder :Dividend :Divisor) 0))]
- op (se :Dividend "/ :Divisor)
- end
-
-
- ;
- ; B U T T O N O B J E C T D E F I N I T I O N
- ;
- ; The Button is a QuickDraw contsruct similar to a Mac control.
- ; The button is a rounded rectangle and contains a text label.
- ; Clicking on the button causes it to reverse and output its label.
- ;
-
- make "Button Something
-
-
- ask :Button [to exist :Window :Left :Top :Label]
- usual.exist
- have "HoldState
- havemake "ButtonHeight ask :Window [WFontSize]
- havemake "ButtonWidth ask :Window [TextWidth :Label]
- havemake "ButtonWindow :Window
- havemake "ButtonLabel :Label
- havemake "X0 :Left
- havemake "Y0 :Top
- havemake "X1 :X0 + :ButtonWidth + 8
- havemake "Y1 :Y0 + :ButtonHeight + 8
- havemake "ButtonRect (list :X0 :Y0 :X1 :Y1)
- LocalMake "Me self
- ask :ButtonWindow [Make "ButtonList se :me :ButtonList]
- DisplayButton
- op :ButtonWidth + 8
- end
-
-
- ;
- ; DisplayButton procedure. Uses QuickDraw.
- ;
-
- ask :Button [to DisplayButton]
- LocalMake "HoldState ask :ButtonWindow [GetPenState]
- LocalMake "TX0 :X0
- LocalMake "TY0 :Y0
- LocalMake "Rect :ButtonRect
- LocalMake "Label :ButtonLabel
- LocalMake "Height :ButtonHeight
- LocalMake "Black [255 255 255 255 255 255 255 255]
- LocalMake "White [0 0 0 0 0 0 0 0]
- ask :ButtonWindow [SetPenMode "Paint]
- ask :ButtonWindow [SetPenSize 2 2]
- ask :ButtonWindow [SetPenPat :Black]
- ask :ButtonWindow [FrameRoundRect :Rect 8 8]
- ask :ButtonWindow [SetPenPat :White]
- ask :ButtonWindow [PaintRoundRect (InsetRect :Rect 2 2) 8 8]
- ask :ButtonWindow [SetPenPat :Black]
- ask :ButtonWindow [MoveTo :TX0 :TY0]
- ask :ButtonWindow [Move 4 :Height]
- ask :ButtonWindow [type :Label]
- ask :ButtonWindow [SetPenState :HoldState]
- end
-
-
- ;
- ; Button is clicked. Reverse it. Wait for the button to be
- ; released. Reverse the button again.
- ;
-
- ask :Button [to ClickButton]
- LocalMake "Rect :ButtonRect
- Ask :ButtonWindow [InvertRoundRect (InsetRect :Rect 2 2) 8 8]
- toot 1000 128 .125
- while [ButtonP] []
- Ask :ButtonWindow [InvertRoundRect (InsetRect :Rect 2 2) 8 8]
- end
-
-
- ;
- ; Button Instantiation.
- ; Note: we don't care about the names of the buttons - only their
- ; positions and labels. Therefore, we can use the primitive .gensym
- ; for naming.
- ;
-
- to MakeSomeButtons :WhichWindow
- LocalMake "PadX0 86
- LocalMake "XInc 3
- LocalMake "PadY0 180
- LocalMake "PadY1 228
- LocalMake "TopRow [0 1 2 3 4 |Next| |O.K.!|]
- LocalMake "BottomRow [5 6 7 8 9 |Help| |Oops!|]
- MakeSomeButtons2 :PadX0 :PadY0 :XInc :TopRow :WhichWindow
- MakeSomeButtons2 :PadX0 :PadY1 :XInc :BottomRow :WhichWindow
- end
-
- to MakeSomeButtons2 :X0 :Y0 :XInc :ButtonList :WhichWindow
- LocalMake "X :X0
- LocalMake "I 0
- Repeat Count :ButtonList
- _ [LocalMake "Symbol .gensym
- _ LocalMake :Symbol kindof :Button
- _ LocalMake "I :I + 1
- _ LocalMake "Label item :I :ButtonList
- _ LocalMake "X :X + :XInc +
- _ ask thing :Symbol [exist :WhichWindow :X :Y0 :Label]
- _ ]
- end
-
-
-
- ;
- ; D E F I N E M E N U O B J E C T S
- ;
-
- make "ProblemMenu oneof Menu
-
- ask :ProblemMenu [SetTitle "Problem]
- ask :ProblemMenu [SetUpItems [
- _ |Addition| [ask ActionWindow [HaveMake "WhatKind "+]]
- _ |Subtraction| [ask ActionWindow [HaveMake "WhatKind "-]]
- _ |Multiplication| [ask ActionWindow [HaveMake "WhatKind "*]]
- _ |Division| [ask ActionWindow [HaveMake "WhatKind "/]]
- _ |Mixed| [ask ActionWindow [HaveMake "WhatKind "Mixed]]]]
-
- ask :ProblemMenu [install]
-
-
- ;
- ; Start things going!;
- ;
-
- make "MathWindow oneof :GameWindow
- MakeSomeButtons :MathWindow
-